/* -*- mode:c++ -*- ********************************************************
 * file:        BaseNetwLayer_SRT_2.h
 *
 * author:      Daniel Willkomm
 *
 * copyright:   (C) 2004 Telecommunication Networks Group (TKN) at
 *              Technische Universitaet Berlin, Germany.
 *
 *              This program is free software; you can redistribute it
 *              and/or modify it under the terms of the GNU General Public
 *              License as published by the Free Software Foundation; either
 *              version 2 of the License, or (at your option) any later
 *              version.
 *              For further information see file COPYING
 *              in the top level directory
 *
 *              Additions : Stattic Routing Table
 *
 ***************************************************************************
 * part of:     framework implementation developed by tkn
 * description: network layer: general class for the network layer
 *              subclass to create your own network layer
 **************************************************************************/


#ifndef SIMPLE_NETW_LAYER_SRT_2_H
#define SIMPLE_NETW_LAYER_SRT_2_H

#include <BaseLayer.h>

#include <ArpInterface.h>
#include <Netw80211Pkt_m.h>
#include <SimpleAddress.h>

#include <NetwToMacControlInfo.h>
#include <MacToNetwControlInfo.h>

// Global Variables
//int addrVec10Hosts_1[10] = {18,26,34,42,50,58,66,74,82,90};
//int addrVec4Hosts_1[4] = {12,20,28,36}; //network addresses !!!
//int addrVec3Hosts_1[3] = {11,19,27};
int networkAddressMapSRT1[10];
int networkAddressMapGlbl1[30];


/**
 * @brief Base class for the network layer
 *
 * @ingroup netwLayer
 * @ingroup baseModules
 * @author Daniel Willkomm
 **/
class BaseNetwLayer_SRT_2 : public BaseLayer
{
public:
	/** @brief Message kinds used by this layer.*/
	enum BaseNetwMessageKinds {
		/** @brief Stores the id on which classes extending BaseNetw should
		 * continue their own message kinds.*/
		LAST_BASE_NETW_MESSAGE_KIND = 24000,
	};
	/** @brief Control message kinds used by this layer.*/
	enum BaseNetwControlKinds {
		/** @brief Stores the id on which classes extending BaseNetw should
		 * continue their own control kinds.*/
		LAST_BASE_NETW_CONTROL_KIND = 24500,
	};

protected:

	//=====================
	// A D D I T I O N - SRT

	unsigned numForwardedPackets;
	unsigned numberTransmittedPacketsTwoHops;
	unsigned numberTransmittedPacketsOneHop;
	unsigned numberReceivedOneHop;
	unsigned numberTtlZeroReceived;
	unsigned numberReceivedTwoHop;


	//=====================
	// A D D I T I O N - SRT

	bool twoHop;

	bool chainTopol;

	bool isSwitch;
	/** @brief time after when the module gets bored and starts jabbering. */
	simtime_t boredTime;

	int maxTtl;

	int ip;

	unsigned long runningSeqNumber;

	typedef std::map<int, int> RoutingTable;

	//RoutingTable routingTable;   //forwarding table
//	RoutingTable forwardingTable;   //forwarding table
//	RoutingTable targetForwardTable;
//	RoutingTable oneHopDestTable;   //forwarding table
//	RoutingTable twoHopDestTable;   //forwarding table
//	RoutingTable destinationTable;

	RoutingTable forwardingTableRT;   //forwarding table
	RoutingTable targetForwardTableRT;
	RoutingTable oneHopDestTableRT;   //forwarding table
	RoutingTable twoHopDestTableRT;   //forwarding table
	RoutingTable destinationTableRT;

	int netwAddr;

	double numHostsInRun;
	double numHosts;

	int inputAdressVec[];

	//=====================


    /**
     * @brief Length of the Netw80211Pkt header
     * Read from omnetpp.ini
     **/
    int headerLength;

    /** @brief Pointer to the arp module*/
    ArpInterface* arp;

    /** @brief cached variable of my network address */
    int myNetwAddr;

    /** @brief Enables debugging of this module.*/
    bool coreDebug;

public:
    //Module_Class_Members(BaseNetwLayer,BaseLayer,0);

    /** @brief Initialization of the module and some variables*/
    virtual void initialize(int);

    // A D D I T I O N - SRT
    virtual void finish();


  protected:
    /**
     * @name Handle Messages
     * @brief Functions to redefine by the programmer
     *
     * These are the functions provided to add own functionality to your
     * modules. These functions are called whenever a self message or a
     * data message from the upper or lower layer arrives respectively.
     *
     **/
    /*@{*/

    // FORWARD
    void forwardPacket(Netw80211Pkt* pkt, int nextHop)
    {
    	Netw80211Pkt* fwd = new Netw80211Pkt(pkt->getName(), pkt->getKind());
    	int macAddr;
    	fwd->setDestAddr(pkt->getFinalDestAddr());
       	fwd->setFinalDestAddr(pkt->getFinalDestAddr());
        fwd->setSrcAddr(pkt->getSrcAddr());
    	fwd->setSeqNum(pkt->getSeqNum());
    	fwd->setTtl(pkt->getTtl() - 1);
    	//ev << "FORWARDING to final destination " << fwd->get<< << << "\n";
    	macAddr = arp->getMacAddr(pkt->getFinalDestAddr());
    	NetwToMacControlInfo* cInfo = new NetwToMacControlInfo(macAddr);

    	fwd->setControlInfo(cInfo);
    	fwd->encapsulate(pkt);
    	sendDown(fwd);
    }
    //
    /** @brief Handle messages from upper layer */
    virtual void handleUpperMsg(cMessage* msg);

    /** @brief Handle messages from lower layer */
    virtual void handleLowerMsg(cMessage* msg);

    /** @brief Handle self messages */
    virtual void handleSelfMsg(cMessage* msg){
	error("BaseNetwLayer does not handle self messages");
    };

    /** @brief Handle control messages from lower layer */
    virtual void handleLowerControl(cMessage* msg);

    /** @brief Handle control messages from lower layer */
    virtual void handleUpperControl(cMessage* msg){
        error("BaseNetwLayer does not handle control messages");
    };

    /*@}*/

    /** @brief decapsulate higher layer message from Netw80211Pkt */
    virtual cMessage* decapsMsg(Netw80211Pkt*);

    /** @brief Encapsulate higher layer packet into an Netw80211Pkt*/
    virtual Netw80211Pkt* encapsMsg(cPacket*);
};

#endif
